#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<time.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<algorithm>
namespace xtb
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		vector()
		{

		}
		~vector()
		{
			if (_start)
			{
				delete[]_start;
				_start = _finish = _outward = nullptr;
			}
		}
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator begin()const
		{
			return _start;
		}
		const_iterator end()const
		{
			return _finish;
		}
		void swap(vector<T>& p)
		{
			std::swap(_start, p._start);
			std::swap(_finish, p._finish);
			std::swap(_outward, p._outward);
		}
		size_t size()const
		{
			return _finish - _start;
		}
		size_t capacity()const
		{
			return _outward - _start;
		}
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t siz = size();
				iterator tmp = new T[n];
				if (_start)
				{
					memcpy(tmp, _start, size() * sizeof(T));
					delete[]_start;
				}
				_start = tmp;
				_finish = _start + siz;
				_outward = _start + n;
			}
		}
		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return *this;
		}
		vector<T>& operator[](size_t pos)
		{
			return _start[pos];
		}
		void push_back(const T& ch)
		{
			if (_finish == _outward)
			{
				size_t n = capacity() == 0 ? 4 : capacity() * 2;
				reserve(n);
			}
			*_finish = ch;
			++_finish;
		}
		void pop_back()
		{
			assert(_finish != nullptr);
			--_finish;
		}
		vector(const vector<T>& p)
		{
			iterator tmp = new T[p.capacity()];
			memcpy(tmp, p._start, p.size() * sizeof(T));
			delete[]_start;
			_start = tmp;
			_finish = _start + p.size();
			_outward = _start + p.capacity();
		}
		void insert(iterator postion, const T ch)
		{
			assert(postion <= _finish);
			if (_finish == _outward)
			{
				size_t len = postion - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				postion = _start + len;
			}
			memmove(postion + 1, postion, (_finish - postion) * sizeof(T));
			*postion = ch;
			++_finish;
		}
		void erase(iterator pos)
		{
			assert(pos >= _start && pos <= _finish);
			memmove(pos, pos + 1, (_finish - pos - 1) * sizeof(T));
			--_finish;

		}
		//void insert(iterator pos, const T& x)
		//{
		//	assert(pos >= _start && pos <= _finish);

		//	if (_finish == _outward)
		//	{
		//		size_t len = pos - _start;
		//		reserve(capacity() == 0 ? 4 : capacity() * 2);
		//		pos = _start + len;
		//	}

		//	memmove(pos + 1, pos, sizeof(T) * (_finish - pos));
		//	*pos = x;

		//	++_finish;
		//}

	private:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _outward = nullptr;
	};
	void print(const vector<int>& t)
	{
		for (const auto& value : t)
		{
			cout << value << " ";
		}
		cout << endl;
	}
	void test1()
	{
		vector<int> a;
		a.push_back(1);
		a.push_back(2);
		a.push_back(3);
		a.push_back(4);
		print(a);
	}
	void test2()
	{
		vector<int> a;
		a.push_back(1);
		a.push_back(2);
		a.push_back(3);
		a.push_back(4);
		print(a);
		vector<int> b;
		b = a;
		print(b);
	}
	void test3()
	{
		vector<int> a;
		a.push_back(1);
		a.push_back(2);
		a.push_back(3);
		a.push_back(4);
		auto it = a.begin();
		++it;
		a.insert(it, 8);
		print(a);
	}
	void test4()
	{
		vector<int> a;
		a.push_back(1);
		auto it = a.begin();
		a.erase(it);
		print(a);
		a.push_back(2);
		print(a);
	}
}